﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Reflection;

namespace GameLogic.Controls
{
    [TemplatePart(Name = C_GamePauseButtonName, Type = typeof(Button))]
    [TemplatePart(Name = C_GameContinueButtonName, Type = typeof(Button))]
    [TemplatePart(Name = C_TimerControlName, Type = typeof(TimerControl))]
    [TemplatePart(Name = C_LifeControlName, Type = typeof(LifeControl))]
    [TemplatePart(Name = C_ScoreControlName, Type = typeof(ScoreControl))]
    [TemplatePart(Name = C_GameContentName, Type = typeof(Grid))]
    public class GameControl : Control
    {
        const string C_GamePauseButtonName = "_gamePauseButton";
        const string C_GameContinueButtonName = "_gameContinueButton";
        const string C_TimerControlName = "_timer";
        const string C_LifeControlName = "_lives";
        const string C_ScoreControlName = "_scores";
        const string C_GameContentName = "_gameContent";

        Grid gameContent;
        TimerControl timer;
        LifeControl lives;
        ScoreControl scores;
        Button gamePauseButton;
        Button gameContinueButton;

        IGameFeatures Game;
        bool _loaded = false;

        public GameControl()
        {
            this.DefaultStyleKey = typeof(GameControl);

            if (DesignerProperties.IsInDesignTool)
            {
                return;
            }

            this.Loaded += (s2, e2) =>
                {
                    if (_loaded)
                    {
                        return;
                    }
                    _loaded = true;

                    // OS: Hack
                    if (GameContainer.GameControlStatic.Parent != null)
                    {
                        Grid parent = GameContainer.GameControlStatic.Parent as Grid;
                        parent.Children.Remove(GameContainer.GameControlStatic);
                    }

                    var game = GameContainer.GameControlStatic;
                    gameContent.Children.Clear();
                    gameContent.Children.Add(game);
                    Game = game as IGameFeatures;

                    if (Game.IsTimeBased)
                    {
                        timer.Visibility = System.Windows.Visibility.Visible;
                        timer.TimerDefeat += (s, e) =>
                            {
                                OnGameOver();
                            };
                    }
                    else
                    {
                        timer.Visibility = System.Windows.Visibility.Collapsed;
                    }

                    if (Game.IsLifeBased)
                    {
                        lives.Visibility = System.Windows.Visibility.Visible;
                        lives.LivesChanged += (s, e) =>
                            {
                              
                            };

                        lives.LivesDefeat += (s, e) =>
                            {
                                OnGameOver();
                            };
                    }
                    else
                    {
                        lives.Visibility = System.Windows.Visibility.Collapsed;
                    }

                    if (this.Game == null)
                    {
                        MessageBox.Show("Game content does not implement IGameFeatures!", "Warning", MessageBoxButton.OK);
                        return;
                    }
                    else
                    {
                        // Register Events to change game properties and handle game property change events
                        this.Game.ScoresChanged += (s, e) =>
                        {
                            scores.Add(e.Scores);
                        };

                        this.Game.LivesChanged += (s, e) =>
                        {
                            lives.Add(e.Lives);
                        };

                        this.Game.GameOver += (s, e) =>
                        {
                            OnGameOver();
                        };

                        this.Game.TimeChanged += (s, e) =>
                            {
                                if (e.ResetTimer)
                                {
                                    timer.Stop();
                                }
                                else if (e.PauseTimer)
                                {
                                    timer.Pause();
                                }
                                else if (e.ResumeTimer)
                                {
                                    timer.Start();
                                }
                                else if (e.TimeInSeconds != 0)
                                {
                                    timer.Add(new TimeSpan(0, 0, e.TimeInSeconds));
                                };
                            };

                        StartGame();
                    }
                };
        }

        private void StartGame()
        {
            if (Game.IsTimeBased)
            {
                timer.StartValue = Game.GameDuration;
                timer.Start();
            }

            scores.Initialize();
            lives.Initialize();

            Game.Start();
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            timer = GetTemplateChild(C_TimerControlName) as TimerControl;
            scores = GetTemplateChild(C_ScoreControlName) as ScoreControl;
            lives = GetTemplateChild(C_LifeControlName) as LifeControl;
            gameContent = GetTemplateChild(C_GameContentName) as Grid;
            gamePauseButton = GetTemplateChild(C_GamePauseButtonName) as Button;
            gameContinueButton = GetTemplateChild(C_GameContinueButtonName) as Button;

            if (DesignerProperties.IsInDesignTool)
            {
                return;
            }
            
            //timer.TimerDefeat += new EventHandler(timer_TimerDefeat);
            //lives.LivesDefeat += new EventHandler(lives_LivesDefeat);
            //scores.ScoresDefeat += new EventHandler(scores_ScoresDefeat);
            //scores.ScoresVictory += new EventHandler(scores_ScoresVictory);
        }

        private void OnGameOver()
        {
            Game.Stop();
            timer.Stop();

            if (Game.IsLifeBased && lives.CurrentValue < 0)
            {
                // Zu ende, weil kein Leben mehr
            }
            else if (Game.IsTimeBased && timer.CurrentValue < timer.DefeatValue)
            {
                // Zuende, weil Zeit zuende
            }
            else
            {
                // Game hat selber gesagt das es zu ende ist.
            }

            GameContainer.LastPoints = scores.CurrentValue;

            // Reset scores and lives
            scores.Initialize();
            lives.Initialize();

            string url = Const.HighscorePageUrl;
            Uri uri = new Uri(url, UriKind.Relative);
            GameContainer.NavigationService.Navigate(uri);
        }

        // OS hier passiert nix
        //// Score control fired victory
        //void scores_ScoresVictory(object sender, EventArgs e)
        //{
        //    timer.Pause();

        //    GameOverEventArgs args = new GameOverEventArgs();
        //    args.GameOverState = GameOverState.Victory;
        //}

        //// Score control fired defeat
        //void scores_ScoresDefeat(object sender, EventArgs e)
        //{
        //    timer.Pause();

        //    GameOverEventArgs args = new GameOverEventArgs();
        //    args.GameOverState = GameOverState.Defeat;
        //}

        //// Life control fired defeat
        //void lives_LivesDefeat(object sender, EventArgs e)
        //{
        //    timer.Pause();

        //    GameOverEventArgs args = new GameOverEventArgs();
        //    args.GameOverState = GameOverState.Defeat;
        //    //args.HighscoreRank = highscores.GetRank(scores.CurrentValue);
        //}
        
        //// Timer control fired defeat
        //void timer_TimerDefeat(object sender, EventArgs e)
        //{
        //    GameOverEventArgs args = new GameOverEventArgs();
        //    args.GameOverState = GameOverState.Defeat;
        //    //args.HighscoreRank = highscores.GetRank(scores.CurrentValue);
        //}
    }
}
